{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Isi Penting Generator: Headline News Style"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Generate a long text output with the style of a news headline when given important facts (isi penting in Malay)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div class=\"alert alert-info\">\n",
    "\n",
    "This tutorial is available as an IPython notebook at [Malaya/example/isi-penting-generator-headline-news-style](https://github.com/huseinzol05/Malaya/tree/master/example/isi-penting-generator-headline-news-style).\n",
    "    \n",
    "</div>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div class=\"alert alert-warning\">\n",
    "\n",
    "The results you see here are generated using stochastic methods. Learn more about the stochastic process on <a href=\"https://en.wikipedia.org/wiki/Stochastic_process\" target=\"_blank\">Wikipedia</a>\n",
    "    \n",
    "</div>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "CPU times: user 3.01 s, sys: 503 ms, total: 3.51 s\n",
      "Wall time: 3.3 s\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/home/maguswyvern/PythonVenvs/dev-malaya/lib/python3.10/site-packages/malaya/tokenizer.py:214: FutureWarning: Possible nested set at position 3397\n",
      "  self.tok = re.compile(r'({})'.format('|'.join(pipeline)))\n",
      "/home/maguswyvern/PythonVenvs/dev-malaya/lib/python3.10/site-packages/malaya/tokenizer.py:214: FutureWarning: Possible nested set at position 3927\n",
      "  self.tok = re.compile(r'({})'.format('|'.join(pipeline)))\n"
     ]
    }
   ],
   "source": [
    "%%time\n",
    "import malaya\n",
    "from pprint import pprint"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### List all available HuggingFace transformers"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The `malaya` library has a built in function to find all available transformers for this task. As of writing we have two transformers which are:\n",
    "\n",
    "1. mesolitica/finetune-isi-penting-generator-t5-base-standard-bahasa-cased <br>\n",
    "https://huggingface.co/mesolitica/finetune-isi-penting-generator-t5-base-standard-bahasa-cased\n",
    "   \n",
    "2. mesolitica/finetune-isi-penting-generator-t5-small-standard-bahasa-cased <br>\n",
    "https://huggingface.co/mesolitica/finetune-isi-penting-generator-t5-small-standard-bahasa-cased"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'mesolitica/finetune-isi-penting-generator-t5-small-standard-bahasa-cased': {'Size (MB)': 242,\n",
       "  'ROUGE-1': 0.24620333,\n",
       "  'ROUGE-2': 0.05896076,\n",
       "  'ROUGE-L': 0.15158954,\n",
       "  'Suggested length': 1024},\n",
       " 'mesolitica/finetune-isi-penting-generator-t5-base-standard-bahasa-cased': {'Size (MB)': 892,\n",
       "  'ROUGE-1': 0.24620333,\n",
       "  'ROUGE-2': 0.05896076,\n",
       "  'ROUGE-L': 0.15158954,\n",
       "  'Suggested length': 1024}}"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "malaya.generator.isi_penting.available_huggingface"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "tested on semisupervised summarization on unseen AstroAwani 20 news, https://github.com/huseinzol05/malay-dataset/tree/master/summarization/semisupervised-astroawani\n",
      "each news compared ROUGE with 5 different generated texts.\n",
      "\n"
     ]
    }
   ],
   "source": [
    "print(malaya.generator.isi_penting.info)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "---"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Load HuggingFace\n",
    "\n",
    "The Generator transformer in `malaya` is quite unique, most of the text generative model we found on the internet like GPT2 or Markov simply just continue the prefix input from user, but not for our Generator transformer. \n",
    "\n",
    "We want to generate an article or karangan like high school when the users give 'isi penting' or important facts for the article."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "```python\n",
    "def huggingface(\n",
    "    model: str = 'mesolitica/finetune-isi-penting-generator-t5-base-standard-bahasa-cased',\n",
    "    force_check: bool = True,\n",
    "    **kwargs,\n",
    "):\n",
    "    \"\"\"\n",
    "    Load HuggingFace model to generate text based on isi penting.\n",
    "\n",
    "    Parameters\n",
    "    ----------\n",
    "    model: str, optional (default='mesolitica/finetune-isi-penting-generator-t5-base-standard-bahasa-cased')\n",
    "        Check available models at `malaya.generator.isi_penting.available_huggingface`.\n",
    "    force_check: bool, optional (default=True)\n",
    "        Force check model one of malaya model.\n",
    "        Set to False if you have your own huggingface model.\n",
    "\n",
    "    Returns\n",
    "    -------\n",
    "    result: malaya.torch_model.huggingface.IsiPentingGenerator\n",
    "    \"\"\"\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "You are using the default legacy behaviour of the <class 'transformers.models.t5.tokenization_t5.T5Tokenizer'>. This is expected, and simply means that the `legacy` (previous) behavior will be used so nothing changes for you. If you want to use the new behaviour, set `legacy=False`. This should only be set if you understand what it means, and thoroughly read the reason why this was added as explained in https://github.com/huggingface/transformers/pull/24565\n"
     ]
    }
   ],
   "source": [
    "model = malaya.generator.isi_penting.huggingface()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Here is the `generate` function and the parameters it expects. "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "```python\n",
    "def generate(\n",
    "    self,\n",
    "    strings: List[str],\n",
    "    mode: str = 'surat-khabar',\n",
    "    **kwargs,\n",
    "):\n",
    "    \"\"\"\n",
    "    generate a long text given a isi penting.\n",
    "\n",
    "    Parameters\n",
    "    ----------\n",
    "    strings : List[str]\n",
    "    mode: str, optional (default='surat-khabar')\n",
    "        Mode supported. Allowed values:\n",
    "\n",
    "        * ``'surat-khabar'`` - news style writing.\n",
    "        * ``'tajuk-surat-khabar'`` - headline news style writing.\n",
    "        * ``'artikel'`` - article style writing.\n",
    "        * ``'penerangan-produk'`` - product description style writing.\n",
    "        * ``'karangan'`` - karangan sekolah style writing.\n",
    "\n",
    "    **kwargs: vector arguments pass to huggingface `generate` method.\n",
    "        Read more at https://huggingface.co/docs/transformers/main_classes/text_generation\n",
    "\n",
    "    Returns\n",
    "    -------\n",
    "    result: List[str]\n",
    "    \"\"\"\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "---"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Benefits of HuggingFace\n",
    "\n",
    "With the `generate` method you can use Greedy, Beam, Sampling, Nucleus decoder and so much more, read more about it on the [HuggingFace Article on How to Generate](https://huggingface.co/blog/how-to-generate). And recently, HuggingFace also released a new article [Introducing Csearch](https://huggingface.co/blog/introducing-csearch)\n",
    "\n",
    "Let's give a few lines of important facts or isi penting for the model to use to generate text."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "isi_penting = ['Dr M perlu dikekalkan sebagai perdana menteri',\n",
    "              'Muhyiddin perlulah menolong Dr M',\n",
    "              'rakyat perlu menolong Muhyiddin']"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "As above, we can give any isi penting even if it does not make any sense. Now we'll use the `generate` method and pass in a few of the vector arguments mentioned in a previous linked article by HuggingFace."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['KUALA LUMPUR:Perdana Menteri Tan Sri Muhyiddin Yassin perlu meletakkan '\n",
      " 'jawatan sebagai perdana menteri (PM) sekiranya beliau terus gagal membentuk '\n",
      " 'kabinet, kata Setiausaha Agung Bersatu Datuk Seri Hamzah Zainudin. Menurut '\n",
      " 'Hamzah, Muhyiddin perlulah menolong Dr Mahathir memimpin negara ini dengan '\n",
      " 'melakukan perubahan yang terbaik sebagai perdana menteri. Tegas Hamzah, '\n",
      " 'tidak salah untuk PH menyokong Dr Mahathir sebagai perdana menteri selagi Dr '\n",
      " 'Mahathir masih berpegang kepada prinsip asas - prinsip-prinsip tersebut. '\n",
      " '\"Rakyat perlu menolong Muhyiddin dalam mentadbir negara. Hamzah berkata, '\n",
      " 'Muhyiddin mesti terus berusaha menyelesaikan isu-isu yang dihadapi oleh '\n",
      " 'negara selain menjaga integriti dan pentadbiran negara.']\n"
     ]
    }
   ],
   "source": [
    "pprint(model.generate(isi_penting, mode = 'tajuk-surat-khabar',\n",
    "    do_sample=True, \n",
    "    max_length=256, \n",
    "    top_k=50, \n",
    "    top_p=0.95,))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "At this point if you get the following error:\n",
    "\n",
    "<div class=\"alert alert-warning\">\n",
    "    \n",
    "FeatureNotFound: Couldn't find a tree builder with the features you requested: lxml.\n",
    "\n",
    "</div>\n",
    "\n",
    "Try installing `lxml` with `pip install lxml`"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "---"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Previously we set the `top_k` parameter to `50`. A higher `top_k` value means the model considers more candidates, potentially leading to more diversity in the generated text but also increasing the computational cost.\n",
    "\n",
    "Now let's try lowering the parameter down and introduce the `penalty_alpha` argument to decrease randomness."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['Presiden PKR, Datuk Seri Anwar Ibrahim perlu dikekalkan sebagai perdana '\n",
      " 'menteri kerana beliau merupakan individu paling layak untuk memimpin negara. '\n",
      " 'Menurut Ahli Parlimen Port Dickson itu, Muhyiddin juga perlulah menolong Dr '\n",
      " 'M. Beliau juga perlu memastikan Dr Mahathir kekal sebagai perdana menteri '\n",
      " 'sehingga Parlimen dibubarkan bagi memberi laluan kepada Pilihan Raya Umum '\n",
      " 'ke-15 (PRU15). \"Perdana Menteri, Muhyiddin Yassin perlu dikekalkan sebagai '\n",
      " 'perdana menteri. \"Rakyat perlu menolong Muhyiddin.']\n"
     ]
    }
   ],
   "source": [
    "pprint(model.generate(isi_penting, mode = 'tajuk-surat-khabar',\n",
    "    do_sample=True, \n",
    "    max_length=256, \n",
    "    penalty_alpha=0.8, top_k=4,))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Try changing the `isi_penting` variable and rerun the generate method again for more results."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "isi_penting = ['Neelofa tetap dengan keputusan untuk berkahwin akhir tahun ini',\n",
    "              'Long Tiger sanggup membantu Neelofa',\n",
    "              'Tiba-tiba Long Tiger bergaduh dengan Husein Zolkepli']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['KUALA LUMPUR: Walaupun bakal melangsungkan perkahwinan bersama pasangan '\n",
      " 'pilihan hatinya, Neelofa tetap dengan keputusan untuk berkahwin akhir tahun '\n",
      " 'ini. Tidak mahu membiarkan keadaan bertambah parah, Neelofa sanggup membantu '\n",
      " 'Long Tiger untuk ke Makkah demi membantu mutakhir anak-anak kesayangannya '\n",
      " 'itu. \"Long Tiger sanggup membantu Neelofa. Tiba-tiba Long Tiger bergaduh '\n",
      " 'dengan suami saya, Husein Zolkepli. BACA: Selepas berkahwin, Neelofa sedia '\n",
      " 'bantu mahligai Neelofa.']\n"
     ]
    }
   ],
   "source": [
    "pprint(model.generate(isi_penting, do_sample=True, mode = 'tajuk-surat-khabar',\n",
    "    max_length=256,\n",
    "    top_k=50, \n",
    "    top_p=0.95, ))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['KUALA LUMPUR: Penyanyi popular, Neelofa tetap dengan keputusan untuk '\n",
      " 'berkahwin akhir tahun ini selepas dua tahun bergelar ibu tunggal. '\n",
      " '\"Alhamdulillah, selepas dua tahun bergelar ibu tunggal, akhirnya saya sudah '\n",
      " 'mempunyai perancangan untuk berkahwin. \"Alhamdulillah, selepas dua tahun '\n",
      " 'bergelar ibu tunggal, akhirnya saya sudah mempunyai perancangan untuk '\n",
      " 'berkahwin akhir tahun ini. \"Sepanjang tempoh itu, saya juga tidak mahu '\n",
      " 'mengambil sebarang tindakan kerana bimbang akan menjejaskan hubungan. '\n",
      " 'Tiba-tiba Long Tiger bergaduh dengan suaminya, Husein Zolkepli,\" katanya '\n",
      " 'kepada BH Online. Long Tiger sanggup membantu Neelofa.']\n"
     ]
    }
   ],
   "source": [
    "pprint(model.generate(isi_penting, mode = 'tajuk-surat-khabar',\n",
    "    do_sample=True, \n",
    "    max_length=256, \n",
    "    penalty_alpha=0.8, top_k=4,))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "isi_penting = ['Anwar Ibrahim jadi perdana menteri', 'Muhyiddin cemburu jadi PM tepi',\n",
    "              'PAS menggunakan isu sentimen kaum dan agama']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['PKR harus melihat ke kaca mata masyarakat Melayu dan umat Islam yang begitu '\n",
      " 'setia kepada UMNO dan Barisan Nasional (BN), kata Setiausaha Agung PKR, '\n",
      " 'Saifuddin Nasution Ismail. Bukan Umno dan PAS yang menyanggah keputusan '\n",
      " 'Anwar dan Mahathir, kata Saifuddin. \"Muhyiddin cemburu jadi PM tepi, bila '\n",
      " 'Zahid nak naik PM barulah Anwar jadi PM. Anwar kembali jadi PM jika PAS mahu '\n",
      " 'bergabung dengan Umno. Ketika pentadbiran PH, PKR juga dilihat mempunyai '\n",
      " 'sekutu Melayu yang cukup kuat. Sementara itu, mengulas isu sentimen kaum dan '\n",
      " 'agama, Saifuddin berkata PKR tidak boleh guna isu agama dan kaum.']\n"
     ]
    }
   ],
   "source": [
    "pprint(model.generate(isi_penting, do_sample=True, mode = 'tajuk-surat-khabar',\n",
    "    max_length=256))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['PAS menggunakan isu sentimen kaum dan agama sebagai alasan untuk tidak '\n",
      " 'menyokong Datuk Seri Anwar Ibrahim sebagai perdana menteri. Ketua Penerangan '\n",
      " 'PAS Datuk Takiyuddin Hassan berkata, PAS tidak boleh menggunakan isu '\n",
      " 'sentimen kaum dan agama untuk menganggu-gugat pentadbiran kerajaan Pakatan '\n",
      " 'Harapan (PH). \"Ini adalah isu agama dan kaum,\" katanya kepada pemberita di '\n",
      " 'Kuala Lumpur, hari ini. Anwar, 75, menjadi perdana menteri pada 9 Mei 2018 '\n",
      " 'selepas PH menang pada Pilihan Raya Umum ke-13, yang menyaksikan PH '\n",
      " 'membentuk kerajaan persekutuan. Muhyiddin cemburu jadi PM tepi.']\n"
     ]
    }
   ],
   "source": [
    "pprint(model.generate(isi_penting, mode = 'tajuk-surat-khabar',\n",
    "    do_sample=True, \n",
    "    max_length=256, \n",
    "    penalty_alpha=0.8, top_k=4,))"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.12"
  },
  "varInspector": {
   "cols": {
    "lenName": 16,
    "lenType": 16,
    "lenVar": 40
   },
   "kernels_config": {
    "python": {
     "delete_cmd_postfix": "",
     "delete_cmd_prefix": "del ",
     "library": "var_list.py",
     "varRefreshCmd": "print(var_dic_list())"
    },
    "r": {
     "delete_cmd_postfix": ") ",
     "delete_cmd_prefix": "rm(",
     "library": "var_list.r",
     "varRefreshCmd": "cat(var_dic_list()) "
    }
   },
   "types_to_exclude": [
    "module",
    "function",
    "builtin_function_or_method",
    "instance",
    "_Feature"
   ],
   "window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
